﻿using System.Collections.Generic;
using System.Linq;
using Dgg.Anug.Cqrs.Core.Domain.Admin.Events;
using Dgg.Anug.Cqrs.Core.Infrastructure.Data;
using Dgg.Anug.Cqrs.Core.Infrastructure.Eventing;
using Raven.Client;

namespace Dgg.Anug.Cqrs.Core.Application.DefectHandling.Services.Handlers
{
	public class VersionCreatedSnapshotCreator : IHandler<VersionCreated>
	{
		private readonly ISnapshotSession _snapshotSession;

		public VersionCreatedSnapshotCreator(ISnapshotSession snapshotSession)
		{
			_snapshotSession = snapshotSession;
		}

		public bool Handle(VersionCreated e)
		{
			Domain.DefectHandling.AppVersion ds = new Domain.DefectHandling.AppVersion(e.ReceiverId, e.Name);
			_snapshotSession.Save(ds);
			return true;
		}
	}

	public class VersionCreatedEntitiesQueryUpdater : IHandler<VersionCreated>
	{
		private readonly IDocumentSession _modelSession;

		public VersionCreatedEntitiesQueryUpdater(IDocumentSession modelSession)
		{
			_modelSession = modelSession;
		}

		public bool Handle(VersionCreated e)
		{
			if (!documentExists())
			{
				createSupportEntitiesFor(e);
			}
			else
			{
				updateSupportEntitiesFor(e);
			}
			return true;
		}

		private bool documentExists()
		{
			return _modelSession.LuceneQuery<Presentation.Models.DefectHandling.SupportEntities>().Any();
		}

		private void createSupportEntitiesFor(VersionCreated e)
		{
			_modelSession.Store(Presentation.Models.DefectHandling.SupportEntities.FirstWith(
				new Presentation.Models.DefectHandling.AppVersion { Id = e.ReceiverId.ToString(), Name = e.Name }));
		}

		private void updateSupportEntitiesFor(VersionCreated e)
		{
			// is not optimal to get the whole document for adding to an internal array, but...
			var entities = _modelSession.Single<Presentation.Models.DefectHandling.SupportEntities>(
				Presentation.Models.DefectHandling.SupportEntities.TheId);
			var versions = entities.Versions ?? new List<Presentation.Models.DefectHandling.AppVersion>();
			versions.Add(new Presentation.Models.DefectHandling.AppVersion
			{
				Id = e.ReceiverId.ToString(),
				Name = e.Name
			});
			entities.Versions = versions;
		}
	}
}
